package edu.luc.etl.jbunit.tl;

import java.util.ArrayList;
import java.util.List;

/**
 * The formula <code>p \/ q</code> specifies that either <code>p</code>
 * or <code>q</code> or both are true in the current time unit.
 */

public class Or<T> extends Expr<T> {

  private List<Expr<T>> exprs;

  public Or(List<Expr<T>> exprs) {
    this.exprs = exprs;
  }

  public Or(Expr<T> l, Expr<T> r) {
    this(And.toList(l, r));
  }

  public Or(T l, T r) {
    this(new Leaf<T>(l), new Leaf<T>(r));
  }

  public Or(Expr<T> l, T r) {
    this(l, new Leaf<T>(r));
  }

  public Or(T l, Expr<T> r) {
    this(new Leaf<T>(l), r);
  }

  public Or<T> clone() {
    Or<T> result = (Or<T>) super.clone();
    result.exprs = new ArrayList<Expr<T>>(exprs.size());
    for (Expr<T> e : exprs) {
      result.exprs.add(e.clone());
    }
    return result;
  }

  public void reset () { 
    for (Expr<T> e : exprs) {
      e.reset();
    }
  }

  public void tick () { 
    evaluated = false; 
    for (Expr<T> e : exprs) {
      e.tick();
    }
  }

  boolean ev () {
    val = false;
    for (Expr<T> e : exprs) {
      val = val || e.valuate();
    }
    return val;
  }

  void accept(Visitor<T> v) {
    v.visitOr(this);
    for (Expr<T> e : exprs) {
      e.accept(v);
    }
  }
}
